package gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;

import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.MutableComboBoxModel;

import metagrammar.Operator;
import metagrammar.OperatorDescription;
import application.Application;
import application.GlobalContext;
import archivemanagement.OperatorManager;

import com.google.common.collect.ImmutableList;

public class OperatorComboBoxWidget extends JPanel {
    
    private class OperatorWrapper {
        
        private final Operator op;
        private final String name;
        
        public OperatorWrapper(Operator op)
        {
            this.op = op;
            name = OperatorDescription.getDescription(op).getName();
        }
        
        public Operator getOperator()
        {
            return op;
        }
        
        @Override
        public String toString()
        {
            return name != null ? name : op.toString();
        }
    }
    
    private final GlobalContext context;
    private final OperatorManager manager;
    
    private JComboBox<MutableComboBoxModel<OperatorWrapper>> libraryModelSelector;
    private JComboBox<OperatorWrapper> operatorSelector;
    private DefaultComboBoxModel<OperatorWrapper> allOperatorsModel;
    
    public OperatorComboBoxWidget()
    {
        manager = Application.injector.getInstance(OperatorManager.class);
        operatorSelector = new JComboBox<OperatorWrapper>();
        operatorSelector.getRenderer();
        
        DefaultComboBoxModel<MutableComboBoxModel<OperatorWrapper>> libraryModels = new DefaultComboBoxModel<MutableComboBoxModel<OperatorWrapper>>();
        libraryModelSelector = new JComboBox<MutableComboBoxModel<OperatorWrapper>>(libraryModels);
        libraryModelSelector.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                int index = libraryModelSelector.getSelectedIndex();
                MutableComboBoxModel<OperatorWrapper> newModel = libraryModelSelector
                .getItemAt(index);
                if(newModel == allOperatorsModel && newModel.getSize() == 0) {
                    Collection<Operator> operators = manager.loadAll();
                    for(Operator op : operators) {
                        newModel.addElement(new OperatorWrapper(op));
                    }
                }
                operatorSelector.setModel(newModel);
                if(operatorSelector.getItemCount() > 0) {
                    operatorSelector.setSelectedIndex(0);
                }
            }
        });
        libraryModelSelector.setBorder(BorderFactory.createTitledBorder("Library"));
        
        context = Application.injector.getInstance(GlobalContext.class);
        
        ImmutableList<Operator> knownOperators = context.getKnownOperators();
        DefaultComboBoxModel<OperatorWrapper> knownOperatorModel = new DefaultComboBoxModel<OperatorWrapper>() {
            @Override
            public String toString()
            {
                return "Loaded Operators";
            }
        };
        for(Operator op : knownOperators) {
            knownOperatorModel.addElement(new OperatorWrapper(op));
        }
        operatorSelector.setModel(knownOperatorModel);
        
        libraryModels.addElement(knownOperatorModel);
        
        allOperatorsModel = new DefaultComboBoxModel<OperatorWrapper>() {
            @Override
            public String toString()
            {
                return "All Operators";
            }
        };
        libraryModels.addElement(allOperatorsModel);
        
        JPanel spacer = new JPanel();
        spacer.add(libraryModelSelector);
        add(spacer);
        JPanel panel = new JPanel();
        panel.add(operatorSelector);
        add(panel);
    }
    
    /**
     * Add an ActionListener to the combo-box
     * @param l
     */
    public void addActionListener(ActionListener l)
    {
        operatorSelector.addActionListener(l);
    }
    
    public Operator getSelectedOperator()
    {
        return operatorSelector.getItemAt(operatorSelector.getSelectedIndex()).getOperator();
    }
}
